package init.luoyu.easymonitor.server.item.business.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.google.common.collect.Lists;
import init.luoyu.easymonitor.base.model.ServiceResult;
import init.luoyu.easymonitor.base.service.impl.BaseServiceImpl;
import init.luoyu.easymonitor.base.utils.CommonUtil;
import init.luoyu.easymonitor.server.device.business.service.IDeviceInterface;
import init.luoyu.easymonitor.server.device.business.service.IDeviceService;
import init.luoyu.easymonitor.server.device.repository.model.CoreDevice;
import init.luoyu.easymonitor.server.device.repository.model.CoreDeviceInterface;
import init.luoyu.easymonitor.server.item.business.model.base.CreateDeviceMonitorItem;
import init.luoyu.easymonitor.server.item.business.model.base.UpdateDeviceMonitorItem;
import init.luoyu.easymonitor.server.item.business.model.input.AddMonitorInput;
import init.luoyu.easymonitor.server.item.business.service.IInterDeviceMonitorItemService;
import init.luoyu.easymonitor.server.item.business.service.IMonitorItemService;
import init.luoyu.easymonitor.server.item.repository.mapper.DeviceMonitorItemMapper;
import init.luoyu.easymonitor.server.item.repository.model.CoreMonitorItem;
import init.luoyu.easymonitor.server.item.repository.model.DeviceMonitorItem;
import init.luoyu.easymonitor.zabbix.enums.ZabbixMethod;
import init.luoyu.easymonitor.zabbix.model.Item;
import init.luoyu.easymonitor.zabbix.server.ZabbixResponse;
import init.luoyu.easymonitor.zabbix.server.ZabbixServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author LuoYu
 * 2021/5/5
 **/
@Service
@Slf4j
public class InterDeviceMonitorItemServiceImpl extends BaseServiceImpl<DeviceMonitorItem, DeviceMonitorItemMapper, CreateDeviceMonitorItem, UpdateDeviceMonitorItem> implements IInterDeviceMonitorItemService {
    public InterDeviceMonitorItemServiceImpl(DeviceMonitorItemMapper mapper, IService<DeviceMonitorItem> service) {
        super(mapper, service, DeviceMonitorItem.class, "监控项");
    }




    @Resource
    private IDeviceService deviceService;


    @Resource
    private IMonitorItemService monitorItemService;


    @Resource
    private IDeviceInterface deviceInterface;


    @Override
    public ServiceResult<Boolean> addOrUpdateHostItem(AddMonitorInput input) {
        log.info("设备批量添加监控项 ----> 设备id:{}",input.getDeviceId());
        CoreDevice coreDevice = deviceService.getMapper().selectById(input.getDeviceId());
        if(coreDevice == null ) {
            log.error("批量添加监控项时发现设备不存在 ----> 设备id:{}",input.getDeviceId());
            return ServiceResult.error("设备不存在");
        }
        Integer hostId = coreDevice.getHostid();
        Set<Long> itemIdSet = input.getItemSettings().stream().map(AddMonitorInput.ItemSetting::getItemId).collect(Collectors.toSet());
        List<CoreMonitorItem> items = monitorItemService.getMapper().selectBatchIds(itemIdSet);
        if(CommonUtil.isEmptyCollection(items) || items.size() != input.getItemSettings().size()) {
            log.error("批量添加监控项时发现监控项不存在 ----> 监控项ids:{}",itemIdSet);
            return ServiceResult.error("监控项不存在");
        }
        //获取当前设备已有的监控项
        QueryWrapper<DeviceMonitorItem> deviceItemQuery = new QueryWrapper<>();
        deviceItemQuery.select("id","monitorItemId","itemId").eq("isDeleted",false).eq("deviceId",input.getDeviceId());
        List<DeviceMonitorItem> monitorItems = this.getMapper().selectList(deviceItemQuery);
        //未添加过监控项则直接添加并返回
        if(!CommonUtil.isEmptyCollection(monitorItems)) {
            Set<Long> existItemIdSet = monitorItems.stream().map(DeviceMonitorItem::getMonitorItemId).collect(Collectors.toSet());
            items.removeIf(v->existItemIdSet.contains(v.getId()));
        }
        if(CommonUtil.isEmptyCollection(items)) {
            log.warn("没有新增的监控项....");
            return ServiceResult.success(true);
        }
        //批量添加
        return bulkDeviceItem(input.getDeviceId(),hostId,items);
    }

    @Override
    public ServiceResult<Boolean> bulkDeleteHostItem(Long deviceId, List<Long> ids) {
        log.info("批量删除设备监控项 ----> 设备id:{} ---- 监控项id:{}",deviceId,ids);
        QueryWrapper<DeviceMonitorItem> itemQuery = new QueryWrapper<>();
        itemQuery.select("id","deviceId","itemId").eq("isDeleted",false)
                .in("monitorItemId",ids);
        List<DeviceMonitorItem> items = this.getMapper().selectList(itemQuery);
        if(CommonUtil.isEmptyCollection(items) || items.size() < ids.size()) {
            log.error("批量删除监控项失败 ----> 监控项不存在 -- 设备id:{} -- 监控项id:{}",deviceId,ids);
            return ServiceResult.error("监控项不存在");
        }
        List<String> itemIds = items.stream().filter(v->v.getItemId() != null).map(v->String.valueOf(v.getItemId())).collect(Collectors.toList());
        ZabbixResponse response = ZabbixServer.delete(itemIds, ZabbixMethod.ITEM_DELETE);
        if (!response.isSuccess()) {
            log.error("远程删除监控项时发生错误 ----> Error:{}",response.getMsg());
            return ServiceResult.error(response.getMsg());
        }
        this.getService().removeByIds(items.stream().map(DeviceMonitorItem::getId).collect(Collectors.toList()));
        return ServiceResult.success(true);
    }

    /**
     * 批量添加监控项
     * @param deviceId  设备id
     * @param hostId    主机id
     * @param items     监控项列表
     * @return          boolean
     */
    private ServiceResult<Boolean> bulkDeviceItem(Long deviceId,Integer hostId,List<CoreMonitorItem> items) {
        if(CommonUtil.isEmptyCollection(items)) {
            log.error("监控项列表不能为空");
            return ServiceResult.error("监控项列表不能为空");
        }
        //获取设备接口
        QueryWrapper<CoreDeviceInterface> interfaceQuery = new QueryWrapper<>();
        interfaceQuery.select("id","interfaceId").eq("deviceId", deviceId);
        CoreDeviceInterface coreDeviceInterface = deviceInterface.getMapper().selectOne(interfaceQuery);
        Integer interfaceId = coreDeviceInterface.getInterfaceId();
        List<CreateDeviceMonitorItem> deviceMonitorItems = Lists.newArrayList();
        items.forEach(v->{
            Item item = new Item();
            item.setHostid(String.valueOf(hostId));
            item.setKey_(v.getMonitorKey());
            item.setName(v.getItemName());
            item.setInterfaceid(String.valueOf(interfaceId));
            item.setType(v.getType());
            item.setValue_type(v.getValueType());
            item.setDelay("30");
            ZabbixResponse response = ZabbixServer.executeOut(item, ZabbixMethod.ITEM_CREATE);
            if(response.isSuccess()) {
                String itemids = response.getDataMap().get("itemids");
                JSONArray array = JSONArray.parseArray(itemids);
                CreateDeviceMonitorItem monitorItem = new CreateDeviceMonitorItem();
                monitorItem.setDeviceId(deviceId);
                monitorItem.setMonitorItemId(v.getId());
                monitorItem.setDayle("30");
                monitorItem.setItemId(array.getInteger(0));
                deviceMonitorItems.add(monitorItem);
            }
        });
        this.bulkSave(deviceMonitorItems);
        return ServiceResult.success(true);
    }









}
